/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: ProcessSP
 * Author:   ThinkPad
 * Date:     2020/6/24 17:07
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.jt.www.queue.process;

import com.jt.www.enums.issue.InvoiceTypeEnum;
import com.jt.www.enums.issue.IssueEnum;
import com.jt.www.enums.issue.PolicyInterfaceEnum;
import com.jt.www.model.issue.entity.IssuePolicyLogEntity;
import com.jt.www.model.issue.entity.IssueRecordEntity;
import com.jt.www.util.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.util.StringUtil;

import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author xq.wu
 * @Description 【食品  阳光】
 * @create 2020/6/24
 * @since 1.0.0
 */
@Service
public class ProcessSP extends ElecPolicyProcess implements InitializingBean {

    public static final Logger log = LoggerFactory.getLogger(ProcessSP.class);

    @Override
    public void afterPropertiesSet() throws Exception {
        IssuePolicyIfCodeFactory.register(PolicyInterfaceEnum.CODE_12.getIfCode(), this);
    }

    @Override
    public Boolean process(Element rootElement, String ifCode) {
        Element reqPacket = getReqPacket(rootElement);
        Element respPacket = getRespPacket(rootElement);

        String currentTime = DateUtils.getCurrentTime();
        // 投保单号
        String tbNo = rootElement.element("ApplicationFormCode").getStringValue();
        // 保单号
        String policyNo = rootElement.element("PolicyNo").getStringValue();
        // 解析险种
        //String proCode = reqPacket.element("Body").element("Apply").element("PolicyType").getStringValue();
        String proCode = IssueEnum.getProCodeByIfCode(ifCode);

        log.debug("系统时间：{}, [食品险（阳光）]下载电子保单 投保单号：{},保单号：{},产品险种编码：{}", currentTime, tbNo, policyNo, proCode);
        // 入库
        // 入库之前首先判断 是否已经入库  根据投保单号判断
        IssueRecordEntity issueRecordEntity = new IssueRecordEntity();
        issueRecordEntity.setApplicationFormCode(tbNo);
        List<IssueRecordEntity> select = issueRecordEntityMapper.select(issueRecordEntity);
        if (select != null && select.size() > 0) {
            log.info("系统时间：{} ,食品险（阳光）投保单号是: {} 的消息发送重复", currentTime, tbNo);
            // 消息重复，消息直接消费完成。
            return true;
        }
        issueRecordEntity.setPolicyNo(policyNo);
        issueRecordEntity.setProCode(proCode);
        issueRecordEntity.setReqPacket(reqPacket.asXML());
        issueRecordEntity.setResPacket(respPacket.asXML());
        issueRecordEntity.setSendStatus("1");
        String status = respPacket.element("Head").element("ResponseCode").getStringValue();

        if ("0".equals(status)) {
            status = "2";
        } else {
            status = "3";
        }
        // 数据中心返回 的投保单状态
        issueRecordEntity.setStatus(status);
        issueRecordEntity.setCreateTime(currentTime);
        issueRecordEntity.setUpdateTime(currentTime);
        issueRecordEntity.setIfCode(ifCode);
        issueRecordEntityMapper.insert(issueRecordEntity);
        if ("3".equals(status)) {
            // 出单失败或者重复出单，消息直接消费完成，在入库的逻辑后边。
            return true;
        }
        // 消费  ： 需要组织报文，去调用接口
        IssuePolicyLogEntity issuePolicyLogEntity = new IssuePolicyLogEntity();
        String consumeStatus = "1";
        issuePolicyLogEntity.setApplicationFormCode(tbNo);
        issuePolicyLogEntity.setPolicyNo(policyNo);
        issuePolicyLogEntity.setType("1");
        issuePolicyLogEntity.setStatus(consumeStatus);
        issuePolicyLogEntity.setCreateTime(currentTime);
        issuePolicyLogEntity.setUpdateTime(currentTime);
        issuePolicyLogEntity.setProCode(proCode);
        // 组装报文
        Document doc = DocumentHelper.createDocument();
        Element info = doc.addElement("POLICYNO");
        info.addText(policyNo);
        issuePolicyLogEntity.setParam(info.asXML());
        issuePolicyLogEntity.setTimes(0);
        issuePolicyLogEntity.setIfCode(ifCode);
        issuePolicyLogEntityMapper.insert(issuePolicyLogEntity);
        // 只要消息进入消费记录的库，就认为消费成功，修改消息记录表状态,具体有没有成功 记录在消费记录表，有定时任务。
        issueRecordEntity.setSendStatus("2");
        issueRecordEntityMapper.updateByPrimaryKeySelective(issueRecordEntity);
        try {
            // 请求下载保单，成功更新
            log.info(DateUtils.getCurrentTime() + "阳光食品保单号是" + tbNo + "下载保单开始，入参" + info.asXML());
            String seqNo = Long.toString(Math.abs(new Random().nextLong()));
            ResponseEntity<String> responseEntity = dexClient.text("edu", "20190805003", "1.0", seqNo, info.asXML());
            consumeStatus = "2";
            String ebody = responseEntity.getBody();
            log.info(DateUtils.getCurrentTime() + "阳光食品保单号是" + tbNo + "下载保单结束，回参" + responseEntity.getStatusCodeValue() + "," + ebody);
            doc = DocumentHelper.parseText(ebody);
            Element ebodyElement = doc.getRootElement();
            Element data = ebodyElement.element("data");
            if (data == null) {
                log.error("阳光食品请求下载电子保单失败");
                consumeStatus = "3";
            }
            System.out.println("食品险电子保单获取到值" + data + "状态码-- " + consumeStatus);
            String fileId = data.getStringValue();
            issuePolicyLogEntity.setStatus(consumeStatus);
            // 下载电子保单成功，更新数据库，绑定资源
            log.info("阳光食品下载消息 fileId ：{}", fileId);
            bindingResources(tbNo, fileId, issuePolicyLogEntity);
            // 下载电子保单成功，更新数据库，绑定资源
            log.info("实责校责下载消息 fileId ：{}", fileId);
            //获取到地区编码，只有山西地区可以下载发票
            String issuingCompanyId = reqPacket.element("Body").element("Apply").element("InsureComp").element("IssuingCompanyId").getStringValue();
            Map<String, String> invoiceList = getAppcodeInvoiceType(tbNo);
            String fee = respPacket.element("Body").element("Apply").element("Fee").getStringValue();
            //食品山西，金额小于10w默认开具电子发票，别的地区选择电子发票就去开，纸质发票不去开具，金额大于10w元的也不去开具
            if (("301400".equals(issuingCompanyId) && judgingTheAmount(fee)) || (invoiceList.get("invoiceType").equals(InvoiceTypeEnum.ELECTRONIC_INVOICE.getType()) && judgingTheAmount(fee))) { // 有发票
                // 下载电子发票 拼装参数
                IssuePolicyLogEntity t = new IssuePolicyLogEntity();
                consumeStatus = "1";
                t.setApplicationFormCode(tbNo);
                t.setPolicyNo(policyNo);
                t.setType("3");
                t.setStatus(consumeStatus);
                t.setCreateTime(currentTime);
                t.setUpdateTime(currentTime);
                t.setProCode(proCode);
                t.setMainType("3");
                doc = DocumentHelper.createDocument();
                // 组装电子发票的报文
                String serialNo = respPacket.element("Body").element("Apply").element("ApplyId").getStringValue();
                String taxpayerNo = reqPacket.element("Body").element("Apply").element("HolderInfo").element("OrganizationCode").getStringValue();
                info = doc.addElement("INSURENCEINFO");
                doc.setRootElement(info);

                Element policylist = info.addElement("POLICYLIST");
                Element ismerge = policylist.addElement("ISMERGE");
                ismerge.addText("0");
                Element POLICYINFO = policylist.addElement("POLICYINFO");
                Element productcode = POLICYINFO.addElement("PRODUCTCODE");
                productcode.addText("160301");
                POLICYINFO.addElement("SERIALNO").addText(serialNo);
                POLICYINFO.addElement("POLICYNO").addText(policyNo);
                POLICYINFO.addElement("INVOICETYPE").addText("2");
                POLICYINFO.addElement("TAXPAYERNO").addText(taxpayerNo);
                //新增购方信息
                String bankAddress = invoiceList.get("bankAddress");
                String mobile = invoiceList.get("mobile");
                String bankName = invoiceList.get("bankName");
                String bankNo = invoiceList.get("bankNo");
                POLICYINFO.addElement("BANKADDRESS").addText(StringUtils.isEmpty(bankAddress) ? "" : bankAddress);
                POLICYINFO.addElement("MOBILE").addText(StringUtils.isEmpty(mobile) ? "" : mobile);
                POLICYINFO.addElement("BANKNAME").addText(StringUtils.isEmpty(bankName) ? "" : bankName);
                POLICYINFO.addElement("BANKNO").addText(StringUtils.isEmpty(bankNo) ? "" : bankNo);
                Element AMOUNT = policylist.addElement("AMOUNT");
                AMOUNT.addText("1");
                Element TOTALJYJE = policylist.addElement("TOTALJYJE");
                TOTALJYJE.addText(fee);
                t.setParam(info.asXML());
                t.setTimes(0);
                t.setIfCode(ifCode);
                // 电子发票的消费记录入库
                issuePolicyLogEntityMapper.insert(t);
                // 刘高逻辑：直接去下载即可。
                log.info(DateUtils.getCurrentTime() + "阳光食品险投保单号是" + tbNo + "下载发票开始，入参" + info.asXML());
                seqNo = Long.toString(Math.abs(new Random().nextLong()));
                responseEntity = dexClient.text("edu", "20190826044", "1.0", seqNo, info.asXML());
                log.info(DateUtils.getCurrentTime() + "阳光食品险投保单号是" + tbNo + "下载发票结束，回参" + responseEntity.getStatusCodeValue() + "," + responseEntity.getBody());
                // 请求200，继续执行
                log.info("阳光食品险的投保单号是 {}, 保单下载返回值：{}, {}", tbNo, responseEntity.getStatusCodeValue(), responseEntity.getBody());
                consumeStatus = "2";
                if (StringUtil.isNotEmpty(responseEntity.getBody())) {
                    issuePolicyLogEntity.setStatus(consumeStatus);
                    String invoiceFileId = responseEntity.getBody();
                    // 下载成功，更新数据库，绑定资源
                    log.info("阳光食品险 下载消息 invoiceFileId ：{}", invoiceFileId);
                    t.setStatus("2");
                    t.setTimes(1);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                } else {
                    log.error("阳光食品险请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(1);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                }
            }
            return true;
        } catch (Exception e) {
            // 下载电子发票 拼装参数
            downInvoice(ifCode, reqPacket, respPacket, currentTime, tbNo, policyNo, proCode);
            e.printStackTrace();
            issuePolicyLogEntity.setTimes(1);
            issuePolicyLogEntity.setStatus("3");
            issuePolicyLogEntityMapper.updateByPrimaryKeySelective(issuePolicyLogEntity);
        }
        sendEmail(tbNo, "21");
        return true;
    }

    public String getStatus(Element respPacket) {
        String status = respPacket.element("Head").element("ResponseCode").getStringValue();
        if ("0".equals(status)) {
            status = "2";
        } else {
            status = "3";
        }
        return status;
    }

    private void downInvoice(String ifCode, Element reqPacket, Element respPacket, String currentTime, String tbNo, String policyNo, String proCode) {
        String consumeStatus;
        Document doc;
        Element info;
        IssuePolicyLogEntity t = new IssuePolicyLogEntity();
        consumeStatus = "1";
        t.setApplicationFormCode(tbNo);
        t.setPolicyNo(policyNo);
        t.setType("3");
        t.setStatus(consumeStatus);
        t.setCreateTime(currentTime);
        t.setUpdateTime(currentTime);
        t.setProCode(proCode);
        t.setMainType("3");
        doc = DocumentHelper.createDocument();
        // 组装电子发票的报文
        String serialNo = respPacket.element("Body").element("Apply").element("ApplyId").getStringValue();
        String taxpayerNo = reqPacket.element("Body").element("Apply").element("HolderInfo").element("OrganizationCode").getStringValue();
        info = doc.addElement("INSURENCEINFO");
        doc.setRootElement(info);

        Element policylist = info.addElement("POLICYLIST");
        Element ismerge = policylist.addElement("ISMERGE");
        ismerge.addText("0");
        Element POLICYINFO = policylist.addElement("POLICYINFO");
        Element productcode = POLICYINFO.addElement("PRODUCTCODE");
        productcode.addText("160301");
        String fee = respPacket.element("Body").element("Apply").element("Fee").getStringValue();
        POLICYINFO.addElement("SERIALNO").addText(serialNo);
        POLICYINFO.addElement("POLICYNO").addText(policyNo);
        POLICYINFO.addElement("INVOICETYPE").addText("2");
        POLICYINFO.addElement("TAXPAYERNO").addText(taxpayerNo);
        Element AMOUNT = policylist.addElement("AMOUNT");
        AMOUNT.addText("1");
        Element TOTALJYJE = policylist.addElement("TOTALJYJE");
        TOTALJYJE.addText(fee);
        t.setParam(info.asXML());
        t.setTimes(0);
        t.setIfCode(ifCode);
        // 电子发票的消费记录入库
        issuePolicyLogEntityMapper.insert(t);
    }

}